<html>
<head><meta charset="utf-8"><title>Data layout / ABI expert needed · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html">Data layout / ABI expert needed</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="227165249"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227165249" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227165249">(Feb 21 2021 at 12:40)</a>:</h4>
<p>Could someone who knows stuff about <code>repr(C)</code> and the C ABI take a look at <a href="https://github.com/rust-lang/rust/issues/82101">https://github.com/rust-lang/rust/issues/82101</a> and <a href="https://github.com/rust-lang/rust/issues/82100">https://github.com/rust-lang/rust/issues/82100</a>? I am not sure whom to ping for issues like this... Cc <span class="user-mention" data-user-id="119009">@eddyb</span> <span class="user-mention" data-user-id="133247">@bjorn3</span> <span class="user-mention" data-user-id="123586">@nagisa</span></p>



<a name="227165422"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227165422" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227165422">(Feb 21 2021 at 12:43)</a>:</h4>
<p>I think unsound is the correct term for this kind of bug. It can cause UB when linking to C code using <code>#[repr(C)]</code> enums that should be identical to the enums on the C side, but aren't due to the ABI incompatbility.</p>



<a name="227165497"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227165497" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227165497">(Feb 21 2021 at 12:44)</a>:</h4>
<p>That might be</p>



<a name="227165502"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227165502" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227165502">(Feb 21 2021 at 12:44)</a>:</h4>
<p>I am not familiar with the memory layout used by the C abi on the various platforms, so I won't be of much more help.</p>



<a name="227165504"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227165504" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227165504">(Feb 21 2021 at 12:44)</a>:</h4>
<p>I was more hoping someone could confirm whether indeed rustc is implementing the C ABI incorrectly here, which seems like a critical bug regardless of whether it's I-unsound or not</p>



<a name="227165870"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227165870" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227165870">(Feb 21 2021 at 12:52)</a>:</h4>
<p>I think they are similar to <a href="https://github.com/rust-lang/rust/issues/89116">#89116</a>, and <code>T-lang</code> have already made a <a href="https://github.com/rust-lang/rust/issues/81996#issuecomment-780047179">decision</a> there.</p>



<a name="227165889"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227165889" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227165889">(Feb 21 2021 at 12:52)</a>:</h4>
<p>As per <a href="https://github.com/rust-lang/rust/issues/81996">https://github.com/rust-lang/rust/issues/81996</a> its not entirely clear what's our definition of <code>repr(c)</code> is in the first place. If its "exactly what the 'native' C compiler does", then yes, our C ABI impl is not correct. If its "what the 'native' ABI document documents" then at least <a href="https://github.com/rust-lang/rust/issues/82101">#82101</a> is in a debatable state.</p>



<a name="227165913"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227165913" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227165913">(Feb 21 2021 at 12:53)</a>:</h4>
<p>A number of the issues filled by mahkoh involves code that's brushing against implementation-defined behaviour.</p>



<a name="227166127"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227166127" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227166127">(Feb 21 2021 at 12:57)</a>:</h4>
<p>In my memory we have considered egregious C ABI mismatches (like the <a href="https://github.com/rust-lang/rust/issues/82100">#82100</a>) a soundness issue because they would make "correct" unsafe code not behave the way it should.</p>



<a name="227167345"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227167345" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227167345">(Feb 21 2021 at 13:18)</a>:</h4>
<p>For <a href="https://github.com/rust-lang/rust/issues/82101#issuecomment-782852942">https://github.com/rust-lang/rust/issues/82101#issuecomment-782852942</a>:</p>
<blockquote>
<p>Can't this lead to types whose alignment is larger than their size? What happens in C when you put these into an array?</p>
</blockquote>
<p>I don't understand what clang is doing... <a href="https://godbolt.org/z/156h4M">https://godbolt.org/z/156h4M</a></p>



<a name="227169944"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227169944" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227169944">(Feb 21 2021 at 14:08)</a>:</h4>
<p>It looks like <code>sizeof(enum Enum) = 4</code> (the actual size of the type) but <code>sizeof(enum Enum[n])</code> is <code>4 * n</code> rounded up to 128 (the alignment of the type). In particular the elements of the array are densely packed, they are not 128 byte aligned</p>



<a name="227170002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227170002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227170002">(Feb 21 2021 at 14:09)</a>:</h4>
<p>Is this behavior actually defined by any standard? Because it's pretty nuts, I hope we don't have to be bug-ward compatible</p>



<a name="227171802"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227171802" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Chris Denton <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227171802">(Feb 21 2021 at 14:42)</a>:</h4>
<blockquote>
<p><code>repr(C)</code> is intended to mean "match the default C ABI for the target"</p>
</blockquote>
<p>Which to me says it should be bug-ward compatible with the target.</p>



<a name="227171803"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227171803" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Chris Denton <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227171803">(Feb 21 2021 at 14:42)</a>:</h4>
<p>However, an alignment on a C enum is nonsensical, no? The enum must have the same representation (size/alignment) as its underlying type. But it can't have the same alignment if the alignment of the enum itself is changed. So there's a conflict to be resolved? Or ignored, I guess.</p>



<a name="227177156"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227177156" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227177156">(Feb 21 2021 at 16:06)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed/near/227169944">said</a>:</p>
<blockquote>
<p>It looks like <code>sizeof(enum Enum) = 4</code> (the actual size of the type) but <code>sizeof(enum Enum[n])</code> is <code>4 * n</code> rounded up to 128 (the alignment of the type). In particular the elements of the array are densely packed, they are not 128 byte aligned</p>
</blockquote>
<p>so the array elements violate alignment then...?</p>



<a name="227177422"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227177422" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227177422">(Feb 21 2021 at 16:11)</a>:</h4>
<p>increasing the alignment is not invalid or contradictory with the request. The weird thing is that <code>sizeof(enum Enum)</code> returns a size… rather than stride.</p>



<a name="227177536"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227177536" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227177536">(Feb 21 2021 at 16:12)</a>:</h4>
<p>if you ask <code>_Alignof(enum Enum)</code> you get 128 for that example.</p>



<a name="227177572"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227177572" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227177572">(Feb 21 2021 at 16:13)</a>:</h4>
<p>In rust <code>std::mem::size_of</code> returns the stride, unlike in C… it seems?</p>



<a name="227177821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227177821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227177821">(Feb 21 2021 at 16:17)</a>:</h4>
<p><span class="user-mention silent" data-user-id="260325">Chris Denton</span> <a href="#narrow/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed/near/227171802">said</a>:</p>
<blockquote>
<blockquote>
<p><code>repr(C)</code> is intended to mean "match the default C ABI for the target"</p>
</blockquote>
<p>Which to me says it should be bug-ward compatible with the target.</p>
</blockquote>
<p>The C ABI is generally specified by a specification document and not an arbitrary implementation of it. The documents sometimes fail to specify certain situations (e.g. MSVC comes to mind as not specifying the 128 bit integers or their interactions in calling conventions). So the T-lang's take on the problem is still ambiguous.</p>



<a name="227177904"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227177904" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227177904">(Feb 21 2021 at 16:18)</a>:</h4>
<p>Another example and the topic of the issue in questino of this is ZSTs. They are not permitted by the primary implementation on msvc targets (visual studio/msvc toolchain) at all, and not specified by the ABI documents Microsoft publishes on the topic. And so, what should Rust's behaviour there be?</p>



<a name="227178458"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227178458" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227178458">(Feb 21 2021 at 16:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="123586">nagisa</span> <a href="#narrow/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed/near/227177572">said</a>:</p>
<blockquote>
<p>In rust <code>std::mem::size_of</code> returns the stride, unlike in C… it seems?</p>
</blockquote>
<p>in Rust, size == stride. I thought the same was true for C.</p>



<a name="227178489"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227178489" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227178489">(Feb 21 2021 at 16:30)</a>:</h4>
<p>However, if an array with n elements has size <code>4 * n</code> rounded up to something... then the stride is 4, right?</p>



<a name="227178911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227178911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227178911">(Feb 21 2021 at 16:37)</a>:</h4>
<p>Hm, <code>sizeof(struct { uint64_t foo; uint8_t bar; });</code> returns 16... That seems awfully stride-like</p>



<a name="227178964"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227178964" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227178964">(Feb 21 2021 at 16:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed/near/227178458">said</a>:</p>
<blockquote>
<p>in Rust, size == stride. I thought the same was true for C.</p>
</blockquote>
<p>That's what I thought, so what clang does makes no sense to me...<br>
In that example, <code>sizeof(Enum[1]) != sizeof(Enum)</code>: <a href="https://godbolt.org/z/eGEdhj">https://godbolt.org/z/eGEdhj</a></p>



<a name="227179093"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227179093" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227179093">(Feb 21 2021 at 16:41)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed/near/227178458">said</a>:</p>
<blockquote>
<p>in Rust, size == stride. I thought the same was true for C.</p>
</blockquote>
<p>Wouldn't any instance where <code>sizeof(T) &lt; _Alignof(T)</code> make size != stride? That's what happening with clang code here.</p>



<a name="227179172"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227179172" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227179172">(Feb 21 2021 at 16:42)</a>:</h4>
<p><span aria-label="shrug" class="emoji emoji-1f937" role="img" title="shrug">:shrug:</span></p>



<a name="227179182"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227179182" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227179182">(Feb 21 2021 at 16:42)</a>:</h4>
<p>Ah I see, the elements are "packed" in the array. weird lol</p>



<a name="227179271"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227179271" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227179271">(Feb 21 2021 at 16:44)</a>:</h4>
<p><span class="user-mention silent" data-user-id="123586">nagisa</span> <a href="#narrow/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed/near/227179093">said</a>:</p>
<blockquote>
<p>Wouldn't any instance where <code>sizeof(T) &lt; _Alignof(T)</code> make size != stride? That's what happening with clang code here.</p>
</blockquote>
<p>To my knowledge, no C/C++ compiler other than clang does that.</p>



<a name="227246035"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227246035" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227246035">(Feb 22 2021 at 10:30)</a>:</h4>
<blockquote>
<p>Wouldn't any instance where sizeof(T) &lt; _Alignof(T) make size != stride? That's what happening with clang code here.</p>
</blockquote>
<p>Yes (except for size==0). Which is why I said above that size is always a(n integer) multiple of alignment... or at least, it should be, in languages with size==stride.</p>



<a name="227246487"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227246487" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227246487">(Feb 22 2021 at 10:34)</a>:</h4>
<p>And C is such a language... ptr arithmetic on a <code>T *ptr</code> moves <code>ptr</code> in multiples of <code>sizeof(T)</code>, after all. That only makes sense if stride==size.</p>



<a name="227333751"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227333751" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227333751">(Feb 22 2021 at 20:40)</a>:</h4>
<p>I agree that we should follow the C ABI for a target as specified and not as implemented, unless there is literally only one implementation and we do not expect another to arise, or if literally all implementations we are aware of share a matching bug, in which case then being bug-for-bug compatible starts to make sense. This doesn't mean we shouldn't keep an eye on what the clang extensions are doing, just that we shouldn't assume that we need to match it.</p>
<p>We may need to introduce better tools for interacting with such, ah, <strong>impressive</strong> choices by compilers, though, at least on the <code>unsafe</code> level.</p>



<a name="227336170"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227336170" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227336170">(Feb 22 2021 at 20:58)</a>:</h4>
<p>well, in the case of, for example, the windows-MSVC target, there is literally one C compiler</p>



<a name="227339478"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227339478" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227339478">(Feb 22 2021 at 21:22)</a>:</h4>
<p>I think it might make sense to prevent people from doing things with repr(C) that are wildly incompatible with C implementations, if real C code doesn't actually use them.</p>



<a name="227339507"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227339507" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227339507">(Feb 22 2021 at 21:22)</a>:</h4>
<p>Does any real C code use enums with weird alignment settings?</p>



<a name="227354770"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227354770" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Quy Nguyen <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227354770">(Feb 22 2021 at 23:06)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed/near/227339507">said</a>:</p>
<blockquote>
<p>Does any real C code use enums with weird alignment settings?</p>
</blockquote>
<p>But then you get into the overloading issue, as I might want an Enum with a stable ABI with a weird alignment. I've used this before when I wanted to do weird tagging things.</p>



<a name="227357052"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227357052" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227357052">(Feb 22 2021 at 23:25)</a>:</h4>
<p>yeah, repr C being overloaded is the heart of the problem here. I think a split in purpose is what's called for.</p>



<a name="227358325"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227358325" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227358325">(Feb 22 2021 at 23:38)</a>:</h4>
<p>I have used repr C many times in rust code but never for ABI compatibility with C, only for predictable C-ish layout with an actual specification. In these situations <code>repr(Rust)</code> isn't usable because the layout is not guaranteed so UB is always possible (although I'm not sure how often this breaks in practice), and actually taking the C compatibility thing seriously and implementing all these other compiler bugs would also be a move away from a stable specification, so I'm quite opposed to it. What fools we were to think that C was ABI compatible with C! <span aria-label="rolling on the floor laughing" class="emoji emoji-1f923" role="img" title="rolling on the floor laughing">:rolling_on_the_floor_laughing:</span> </p>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> brought up on another thread that repr(C) is also the only allowed repr for extern functions (even Rust-to-Rust!), which means changing this may cause unfixable bugs. (Not all FFI is to actual C, it's sometimes just the common baseline of two non-C implementations.)</p>



<a name="227360002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227360002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227360002">(Feb 22 2021 at 23:54)</a>:</h4>
<p>Indeed, i have a crate on <a href="http://crates.io">crates.io</a> (well, version 0.0.2 of it) that would be broken by a change to how repr(C) currently does ZST values. And the theoretical purpose of the crate was exactly to make a stable way to pass slices into and out of "C" ABI functions.</p>



<a name="227360210"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227360210" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227360210">(Feb 22 2021 at 23:56)</a>:</h4>
<p>Yes, if PhantomData becomes non-zst inside repr(C), i have a lot of broken FFI code.</p>



<a name="227361728"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227361728" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227361728">(Feb 23 2021 at 00:10)</a>:</h4>
<p>PhantomData is a language item though, and a special case in many ways.</p>



<a name="227361747"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227361747" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227361747">(Feb 23 2021 at 00:11)</a>:</h4>
<p>e.g. IIRC it does not influence the alignment of the containing ADT, like other ZSTs would.</p>



<a name="227361809"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227361809" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227361809">(Feb 23 2021 at 00:11)</a>:</h4>
<p>and the thing is: this change <em>would not</em> show up in crater checking. Because the crate doesn't have a test to assert that the struct as a whole is the same size as two usize values, because <em>of course</em> that's the size, and repr(C) is stable, so of course i don't need to assert the size of the struct any more than i need to try asserting that usize and isize are the same size, or any other pedantic assertions.</p>



<a name="227362705"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227362705" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Quy Nguyen <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227362705">(Feb 23 2021 at 00:20)</a>:</h4>
<p>Yeah, right now repr C is one of those things where if I'm doing unsafe mucking or C-style casting within Rust, I'll throw it on to guard against field reordering. Changing it would probably be a pretty big hidden break.</p>



<a name="227396987"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227396987" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227396987">(Feb 23 2021 at 08:35)</a>:</h4>
<blockquote>
<p>We may need to introduce better tools for interacting with such, ah, impressive choices by compilers, though, at least on the unsafe level.</p>
</blockquote>
<p>For now I'd stick to the hypothesis that there's a clang bug here -- it makes no sense that a one-element array of a type would have a different size than the type itself... basically this can lead to UB even in completely innocent C code, like creating a two-element array, getting pointers to both elements and using them. At least one element will definitely not be aligned -&gt; UB. Even by C standards, this does not seem right.^^</p>



<a name="227471027"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227471027" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227471027">(Feb 23 2021 at 17:37)</a>:</h4>
<p>repr(C) is definitely intended to be C-compatible, not just a generic stable layout. But we should indeed look into implementation bugs in clang and others, as well as actual usage in practice, before assuming we have to match every last quirk.</p>



<a name="227475270"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227475270" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227475270">(Feb 23 2021 at 18:02)</a>:</h4>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> If that's the case, then I'd like your initial reaction on two points:<br>
1) PhantomData can continue to be special and still not affect repr C layout <em>even if</em> it turns out that other ZSTs will begin to affect repr C layout<br>
2) We add a dedicated generic stable layout to the language that doesn't change based on the local C compiler's whims.</p>
<p>and if the answer is "I'll have to think about it" that's okay too</p>



<a name="227475494"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227475494" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227475494">(Feb 23 2021 at 18:04)</a>:</h4>
<p>(Currently in lang team meeting, expect slow asynchronous responses.)</p>



<a name="227475578"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227475578" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227475578">(Feb 23 2021 at 18:04)</a>:</h4>
<p>To (2), I'm broadly speaking in favor of something like <code>repr(inorder)</code> or similar.</p>



<a name="227475874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227475874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227475874">(Feb 23 2021 at 18:06)</a>:</h4>
<p>It'd need careful definition, but I'm in favor of the concept.</p>



<a name="227476554"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227476554" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227476554">(Feb 23 2021 at 18:10)</a>:</h4>
<p>For (1), my initial reaction is that I'd <em>generally</em> like ZSTs to behave the same as they do in C by default, to the extent that the C ABI supports them, but I'm fine with making a mechanism for special things like <code>PhantomData</code> and <code>PhantomPinned</code> to opt for a different "don't affect layout at all" approach.</p>



<a name="227476887"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227476887" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227476887">(Feb 23 2021 at 18:12)</a>:</h4>
<p>I personally think that <code>PhantomData</code> and <code>PhantomPinned</code> are not the ideal solutions, and I feel like there'd be a better way to express the same semantics without requiring (for instance) a phantom value to be provided at construction time. But until we have that better mechanism, we should allow those to behave differently than ZSTs in repr(C) if ZSTs in repr(C) stop being ZS.</p>



<a name="227476944"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227476944" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227476944">(Feb 23 2021 at 18:12)</a>:</h4>
<p>We could come up with a new name for "types that never affect layout at all", and flag the phantom types accordingly.</p>



<a name="227479038"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227479038" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227479038">(Feb 23 2021 at 18:25)</a>:</h4>
<p>Well also consider this: what happens to repr(transparent)?</p>
<p>because if it's not changed to match how this C thing then you'll have a very subtle difference exactly where you have the most unsafe code.</p>
<p>specifically</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="c1">// size = 1 usize</span>
<span class="cp">#[repr(transparent)]</span><span class="w"> </span><span class="k">struct</span> <span class="nc">CRef</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="n">p</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">mark</span>: <span class="nc">PhantomData</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="c1">// size = 2 usize</span>
<span class="cp">#[repr(C)]</span><span class="w"> </span><span class="k">struct</span> <span class="nc">ThingX</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="n">x</span>: <span class="nc">CRef</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">capacity</span>: <span class="kt">usize</span>
<span class="p">}</span><span class="w"></span>

<span class="c1">// size = 3 usize!!</span>
<span class="cp">#[repr(C)]</span><span class="w"> </span><span class="k">struct</span> <span class="nc">ThingY</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="n">y</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">mark</span>: <span class="nc">PhantomData</span><span class="o">&lt;'</span><span class="na">a</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">capacity</span>: <span class="kt">usize</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="227479360"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227479360" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227479360">(Feb 23 2021 at 18:27)</a>:</h4>
<p>Given the purpose of <code>repr(transparent)</code>, I think we <em>have</em> to change it to match <code>repr(C)</code>.</p>



<a name="227479504"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227479504" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227479504">(Feb 23 2021 at 18:28)</a>:</h4>
<p>Hmmm. Did the behavior of allowing ZSTs in <code>repr(transparent)</code> make it to stable?</p>



<a name="227479635"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227479635" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227479635">(Feb 23 2021 at 18:29)</a>:</h4>
<p>yes, for quite some time</p>



<a name="227480251"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227480251" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227480251">(Feb 23 2021 at 18:32)</a>:</h4>
<p><span class="user-mention" data-user-id="127859">@Taylor Cramer</span> made a couple of points that <em>should</em> address this completely.</p>



<a name="227480271"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227480271" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227480271">(Feb 23 2021 at 18:32)</a>:</h4>
<p>there were some blog posts exploring the fact that "zst, align 1" becomes an API feature of your type because of <code>repr(transparent)</code></p>



<a name="227480494"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227480494" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227480494">(Feb 23 2021 at 18:34)</a>:</h4>
<p>(i.e. it's a breaking change to depart from that)</p>



<a name="227480773"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227480773" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227480773">(Feb 23 2021 at 18:35)</a>:</h4>
<p>To match the ABI of C, we just need to change the layout behavior of putting a <em><code>repr(C)</code></em> type that would be zero-sized inside another structure with <code>repr(C)</code>. And for that matter, the layout differences primarily seem to come up if you have a <code>repr(align)</code> alignment, or you're a <code>[T; 0]</code> zero-length array and thus have the alignment of <code>T</code>. <code>PhantomData</code> and <code>PhantomPinned</code> aren't <code>repr(C)</code> and aren't <code>repr(align)</code> and don't have an alignment.</p>



<a name="227480862"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227480862" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227480862">(Feb 23 2021 at 18:35)</a>:</h4>
<p>I think if we apply that rule, we should get the correct behavior.</p>



<a name="227481080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227481080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227481080">(Feb 23 2021 at 18:37)</a>:</h4>
<p><span class="user-mention" data-user-id="224471">@Lokathor</span> Does that sound to you like it'd do the right thing?</p>



<a name="227481416"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227481416" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227481416">(Feb 23 2021 at 18:38)</a>:</h4>
<p>Concretely: <code>repr(Rust)</code> 1-ZST fields should not affect the layout of a <code>repr(C)</code> type in any way.</p>



<a name="227481478"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227481478" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227481478">(Feb 23 2021 at 18:39)</a>:</h4>
<p>yes, if we dony change ZSTs in general, just the layout of repr(C) on an empty struct, that should make everyone happy</p>



<a name="227481680"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227481680" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227481680">(Feb 23 2021 at 18:40)</a>:</h4>
<p>It sounds like we also need to fix the handling of alignment, but yeah, those fixes shouldn't change the handling of 1-ZSTs.</p>



<a name="227482720"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227482720" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227482720">(Feb 23 2021 at 18:47)</a>:</h4>
<p>Supporting ZSTs in repr(transparent) was intentional to allow PhantomData/PhantomPinned/etc</p>



<a name="227483126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227483126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227483126">(Feb 23 2021 at 18:49)</a>:</h4>
<p><span class="user-mention" data-user-id="243558">@Steven Fackler</span> Yeah, I remember that. IIRC, we <em>only</em> allow 1-ZSTs (ZSTs with alignment 1) in <code>repr(transparent)</code>.</p>



<a name="227483228"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227483228" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227483228">(Feb 23 2021 at 18:50)</a>:</h4>
<p>That's what this followup was trying to cover: can we write a general rule that fixes <code>repr(C)</code> usage of ZSTs without breaking <code>PhantomData</code>/<code>PhantomPinned</code> and without special-casing those types.</p>



<a name="227483480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227483480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227483480">(Feb 23 2021 at 18:52)</a>:</h4>
<p>And it seems like we can: we can fix the behavior of <code>repr(C)</code> zero-sized types inside <code>repr(C)</code> structures, while still maintaining the property that <code>repr(Rust)</code> 1-ZSTs don't affect layout at all.</p>



<a name="227484377"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227484377" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227484377">(Feb 23 2021 at 18:57)</a>:</h4>
<p>should we introduce a concept of 0-alignment?</p>



<a name="227484516"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227484516" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227484516">(Feb 23 2021 at 18:58)</a>:</h4>
<p>That'd be how you'd mark the types that don't have any effect at all in repr(c) types.</p>



<a name="227484574"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227484574" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227484574">(Feb 23 2021 at 18:58)</a>:</h4>
<p>Though I guess that does sound like a magic number kind of thing</p>



<a name="227484589"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227484589" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227484589">(Feb 23 2021 at 18:58)</a>:</h4>
<p>There's a bunch of places using <code>NonZeroUSize</code> to store alignments, so that scares me.</p>



<a name="227484790"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227484790" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227484790">(Feb 23 2021 at 18:59)</a>:</h4>
<p>I said that and now I'm remembering I wrote code that assumes power-of-two (== nonzero) too.</p>



<a name="227484882"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227484882" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227484882">(Feb 23 2021 at 19:00)</a>:</h4>
<p>The <code>Layout</code> class as a whole gates all its constructors on <code>.is_power_of_two()</code>.</p>



<a name="227484903"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227484903" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227484903">(Feb 23 2021 at 19:00)</a>:</h4>
<p>primarily around use of ctlz_nonzero cttz_nonzero</p>



<a name="227485250"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227485250" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227485250">(Feb 23 2021 at 19:02)</a>:</h4>
<p>(Aside: <a href="https://doc.rust-lang.org/nightly/core/num/struct.NonZeroUsize.html#method.trailing_zeros"><code>NonZeroUSize::leading_zeros</code></a> exists now, on nightly, if you want to avoid some intrinsics usage.)</p>



<a name="227486825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227486825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227486825">(Feb 23 2021 at 19:12)</a>:</h4>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> if i recall the initial issue post properly, a repr(C) zero field type would also need to be size 1 on its own, outside of a larger structure</p>



<a name="227488037"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227488037" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227488037">(Feb 23 2021 at 19:21)</a>:</h4>
<p>/me nods.</p>



<a name="227488055"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227488055" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227488055">(Feb 23 2021 at 19:21)</a>:</h4>
<p>That still wouldn't break the use of Phantom.</p>



<a name="227531098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227531098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227531098">(Feb 24 2021 at 00:48)</a>:</h4>
<p>I think this means that repr(C) ZST's inside repr(transparent) will break</p>



<a name="227531258"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227531258" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227531258">(Feb 24 2021 at 00:50)</a>:</h4>
<p>i.e. this compiles on stable, and probably shouldn't with the revised rules</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">ZST</span><span class="p">;</span><span class="w"></span>

<span class="cp">#[repr(transparent)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">a</span>: <span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="nc">ZST</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="227535658"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227535658" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227535658">(Feb 24 2021 at 01:48)</a>:</h4>
<p>That seems potentially acceptable if nothing uses it.</p>



<a name="227539345"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227539345" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227539345">(Feb 24 2021 at 02:40)</a>:</h4>
<p>(And there's a bunch of <code>repr(transparent)</code> things that we want to break, see <a href="https://github.com/rust-lang/rust/issues/78586#issuecomment-720729169">https://github.com/rust-lang/rust/issues/78586#issuecomment-720729169</a>)</p>



<a name="227540904"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227540904" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227540904">(Feb 24 2021 at 03:03)</a>:</h4>
<p>Well that's a different issue, that's about semver</p>



<a name="227541005"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227541005" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227541005">(Feb 24 2021 at 03:04)</a>:</h4>
<p>Really, the fact that repr(transparent) can cause the compile to break is the best case scenario here; as others have pointed out this is only the tip of the iceberg with most breakage being silent UB</p>



<a name="227568973"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227568973" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227568973">(Feb 24 2021 at 09:14)</a>:</h4>
<p>Maybe I missed something, but it sounds like <a href="https://github.com/dtolnay/ref-cast">ref-cast</a> will be unhappy <strong>silently</strong>:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span><span class="n">ref_cast</span>::<span class="n">RefCast</span><span class="p">;</span><span class="w"></span>

<span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Zst</span><span class="p">;</span><span class="w"></span>

<span class="cp">#[derive(RefCast)]</span><span class="w"></span>
<span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">ContainsZst</span><span class="p">(</span><span class="n">Zst</span><span class="p">);</span><span class="w"></span>

<span class="cp">#[derive(RefCast)]</span><span class="w"></span>
<span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">ContainsZeroSizedArray</span><span class="p">([</span><span class="kt">u8</span><span class="p">;</span><span class="w"> </span><span class="mi">0</span><span class="p">]);</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span>: <span class="kp">&amp;</span><span class="nc">ContainsZst</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ContainsZst</span>::<span class="n">ref_cast</span><span class="p">(</span><span class="o">&amp;</span><span class="n">Zst</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span>: <span class="kp">&amp;</span><span class="nc">ContainsZeroSizedArray</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ContainsZeroSizedArray</span>::<span class="n">ref_cast</span><span class="p">(</span><span class="o">&amp;</span><span class="p">[]);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="227611293"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227611293" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227611293">(Feb 24 2021 at 15:02)</a>:</h4>
<p>I may be missing some subtleties, but wouldn't a warning be a better approach than <em>changing semantics</em>? IIUC, the main problem here is that "for cases where there is no official C ABI / the official C rules do not cover it", such as zero-sized types, there is a discrepancy between Rust's <code>#[repr(C)]</code> semantics and what most C compilers do with the "equivalent" C definition.</p>
<ul>
<li>For instance, <code>#[repr(C)] struct Zst {}</code> <em>vs.</em> <code>typedef struct {} Zst_t;</code></li>
</ul>
<p>If that is the case, a warning would prevent that misconception of "ABI matching", which seems to be the main concern.</p>
<p>From there follows a second concern, which is that of having a way to write / express in Rust a definition that would be equivalent to some nonstandard C idioms (<em>e.g.</em>, how do we write <code>typedef struct {} Zst_t;</code> in Rust)</p>
<p>And we do have the ability to express these semantics: in the case of a zero-sized type, or more specifically, defining a struct with no fields, if most C compilers out there accept it as a align-sized definition, then an equivalent way to write it in Rust would be to define:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[repr(C)]</span><span class="w"> </span><span class="c1">// Warning, this may not match the ABI of common C compilers</span>
<span class="k">struct</span> <span class="nc">Zst</span><span class="p">;</span><span class="w"></span>
<span class="c1">// hint: either remove that annotation or write:</span>
<span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">CZst</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">_cant_be_zero_sized</span>: <span class="nc">MaybeUninit</span><span class="o">&lt;</span><span class="kt">u8</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>There could even be a helper type definition under <code>std::ffi</code>, something like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">CZst</span><span class="o">&lt;</span><span class="n">Payload</span><span class="w"> </span><span class="cm">/* : IsZeroLongArray */</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[();</span><span class="w"> </span><span class="mi">0</span><span class="p">]</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">_payload</span>: <span class="nc">Payload</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">_cant_be_zero_sized</span>: <span class="nc">MaybeUninit</span><span class="o">&lt;</span><span class="kt">u8</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="c1">// &lt;- or make it `#[lang]` special-cased item</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>so as to write:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">MyZst</span><span class="p">(</span><span class="n">CZst</span><span class="p">);</span><span class="w"> </span><span class="c1">// would warn without it</span>

<span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Complex</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">a</span>: <span class="kt">f32</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">_arr</span>: <span class="nc">CZst</span><span class="o">&lt;</span><span class="p">[</span><span class="kt">u64</span><span class="p">;</span><span class="w"> </span><span class="mi">0</span><span class="p">]</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="c1">// would warn without it</span>
<span class="w">    </span><span class="n">b</span>: <span class="kt">u8</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="c1">// …</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>This solution features non-breaking changes, better-defined expectations (thanks to the warning), and a way to still easily interface with these nonstandard C semantics.</p>



<a name="227711906"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227711906" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227711906">(Feb 25 2021 at 03:17)</a>:</h4>
<p><span class="user-mention" data-user-id="232018">@Daniel Henry-Mantilla</span> +1 to that, but how would you propose to handle the clang "over-aligned enum" case <a href="#narrow/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed/near/227167345">above</a>?</p>



<a name="227749022"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227749022" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227749022">(Feb 25 2021 at 10:53)</a>:</h4>
<p>That is left as an exercice to the reader <span aria-label="stuck out tongue" class="emoji emoji-1f61b" role="img" title="stuck out tongue">:stuck_out_tongue:</span></p>



<a name="227750177"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227750177" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227750177">(Feb 25 2021 at 11:04)</a>:</h4>
<p>More seriously, I was / am mostly concerned with breakage <em>w.r.t.</em> <code>#[repr(C)]</code> zero-sized types / 0-long arrays, since they are not that uncommon in the Rust ecosystem (<a href="https://grep.app/search?current=57&amp;q=%5Cs%5C%5B.%2A%3B%200%5C%5D%2C&amp;regexp=true&amp;filter[lang][0]=Rust">grep.app</a>); <code>#[repr(C, align(…)]</code>, otoh, is not as pervasive (I tried <code>grep.app</code>-ing for <code>#[repr(C, align</code>, and on the first few pages it was always applied to <code>struct</code>s).<br>
I don't know enough to judge whether a change is necessary for the over-aligned enum case, but, <strong>in practice</strong>, changing the semantics of for<code>#[repr(C, align…]</code> enums seems to be far less disruptive. I also personally think that <code>#[repr(C)]</code> enums have always been quite underspecified, in Rust (because they are, in C), which is different than the <code>repr(inorder)</code> semantics that were given to <code>#[repr(C)]</code> <code>struct</code>s, so the very concept of "breaking" in that case is less clear cut <span aria-label="smile" class="emoji emoji-1f642" role="img" title="smile">:smile:</span></p>



<a name="227752184"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227752184" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227752184">(Feb 25 2021 at 11:23)</a>:</h4>
<blockquote>
<p>I also personally think that #[repr(C)] enums have always been quite underspecified, in Rust</p>
</blockquote>
<p>Really? I feel like they're very well specified, surprisingly so: <a href="https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md">https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md</a></p>



<a name="227754499"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227754499" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227754499">(Feb 25 2021 at 11:46)</a>:</h4>
<p>Sorry I should have been more clear: I am talking about the <em>size</em> of a <code>#[repr(C)]</code> enum, (which, IIUC, is where there could be breakage regarding over-aligned enums). It's defined as "the size that C woud give", but C does not define what size it gives to an <code>enum</code> <span aria-label="upside down" class="emoji emoji-1f643" role="img" title="upside down">:upside_down:</span></p>



<a name="227754833"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227754833" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227754833">(Feb 25 2021 at 11:49)</a>:</h4>
<p>(IIRC, a C enum must have <del>a size so that it fits in an <code>int</code></del> the size of some integral type, but that type could very well be a <code>uint8_t</code> (<em>e.g.</em>, <code>-fshort-enums</code>))</p>



<a name="227755586"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227755586" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227755586">(Feb 25 2021 at 11:56)</a>:</h4>
<blockquote>
<p>6.7.2.2 Enumeration specifiers<br>
[...]<br>
Constraints<br>
The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.<br>
[...]<br>
Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration.</p>
</blockquote>
<p>So the <code>enum</code> <em>discriminants</em> cannot be bigger than <code>int</code>s, but afterwards it is <em>implementation-defined</em> as to what the size of the so-defined <code>enum</code> is (which, for extra fun, does not affect the type of the <code>enum</code> <em>variants</em> themselves, which remain <code>int</code>s)</p>



<a name="227756145"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227756145" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227756145">(Feb 25 2021 at 12:01)</a>:</h4>
<p>And since in the FFI world, we don't care about discriminants nor variants, just about the ABI of a type, we are left with an implementation-defined integral type (whose choice can depend on the discriminant values, of course)</p>



<a name="227765519"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227765519" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227765519">(Feb 25 2021 at 13:22)</a>:</h4>
<p>in practice they can be larger than ints too.</p>



<a name="227765605"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227765605" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227765605">(Feb 25 2021 at 13:23)</a>:</h4>
<p>In fact Rust here is stricter than most C implementations in that it does not allow repr(C) enums that have discriminants outside of <code>isize</code>.</p>



<a name="227766223"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227766223" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227766223">(Feb 25 2021 at 13:27)</a>:</h4>
<p>How does that work? I assume you don't mean an enum with 2^64 variants, so something like <code>enum Foo { A = 4000000000; }</code>?</p>



<a name="227766378"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227766378" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227766378">(Feb 25 2021 at 13:28)</a>:</h4>
<p>or can variants be doubles or something crazy like that?</p>



<a name="227766466"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227766466" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227766466">(Feb 25 2021 at 13:29)</a>:</h4>
<p>I'm pretty sure you just get an error if the literal is not isize. If the variants wrap, I think the discriminants wrap too?</p>



<a name="227766494"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227766494" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227766494">(Feb 25 2021 at 13:29)</a>:</h4>
<p>I mean in these nonconforming C implementations</p>



<a name="227766760"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227766760" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227766760">(Feb 25 2021 at 13:31)</a>:</h4>
<p>oh, so you can say <code>enum A { FOO = 42ull }</code> on a 32 bit target and get a 64-bit enum IIRC</p>



<a name="227766846"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/227766846" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#227766846">(Feb 25 2021 at 13:32)</a>:</h4>
<p>Idk what the behaviours are otherwise.</p>



<a name="228056355"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Data%20layout%20/%20ABI%20expert%20needed/near/228056355" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Data.20layout.20.2F.20ABI.20expert.20needed.html#228056355">(Feb 27 2021 at 12:46)</a>:</h4>
<p>I'm getting the feeling that Rust's <code>repr(align)</code> and GCC's <code>attribute((aligned))</code> are simply not the same thing, so the bug is written under an incorrect assumption... but let's see what the response is to <a href="https://github.com/rust-lang/rust/issues/82101#issuecomment-787067437">this</a> question.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>